package com.yq.interview.study.thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName SyncAndReentrantLockDemo
 * @Description LOCK相关工具类,精确唤醒
 * 题目多线程之间按顺序调用，实现A->B->C三个线程启动，要求如下：
 * AA打印5次，BB打印10次，CC打印15次
 * 紧接着AA打印5次，BB打印10次，CC打印15次，
 * 重复来10次
 * 一个锁，绑定了三个condition
 * @Author yaoqiang
 * @Date 2020/11/23 13:18
 * @Version 1.0
 */
public class SyncAndReentrantLockDemo {
    public static void main(String[] args) {
        ShareResource shareResource=new ShareResource();
        new Thread(()->{
            for (int i=1;i<=5;i++){
                shareResource.print5();
            }
        },"AA").start();

        new Thread(()->{
            for (int i=1;i<=10;i++){
                shareResource.print10();
            }
        },"BB").start();

        new Thread(()->{
            for (int i=1;i<=15;i++){
                shareResource.print15();
            }
        },"CC").start();

    }

}

class ShareResource{
    private int num=1; //A是1，B是2c是3
    private Lock lock=new ReentrantLock();
    private Condition c1=lock.newCondition();
    private Condition c2=lock.newCondition();
    private Condition c3=lock.newCondition();
    //判断干活，通知，唤醒

    //判断
    public  void print5(){
        lock.lock();
        try {
            //判断
            while (num!=1){
                c1.await();
            }
            //干活
            for (int i=1;i<=5;i++){
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            //通知
            num=2;
            c2.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public  void print10(){
        lock.lock();
        try {
            //判断
            while (num!=2){
                c2.await();
            }
            //干活
            for (int i=1;i<=10;i++){
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            //通知
            num=3;
            c3.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public  void print15(){
        lock.lock();
        try {
            //判断
            while (num!=3){
                c3.await();
            }
            //干活
            for (int i=1;i<=15;i++){
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            //通知
            num=1;
            c1.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }


}